package com.sinodata.bsm.cicp.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.j2ee.statistics.BoundedRangeStatistic;
import javax.management.j2ee.statistics.CountStatistic;
import javax.management.j2ee.statistics.Statistic;
import javax.management.j2ee.statistics.Stats;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.log4j.Logger;
import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
import org.jboss.naming.NamingContextFactory;

public class RmiUtil {
    private static Logger logger = Logger.getLogger(RmiUtil.class);

    public static final String JBOSS = "jboss";

    public static synchronized RMIAdaptor getRmiAdaptor(String address, int port) throws IOException {
        RMIAdaptor rtnVal = null;
        Hashtable<String, Object> connProp = new Hashtable<String, Object>();
        String url = "jnp://" + address + ":" + port;
        connProp.put(Context.PROVIDER_URL, url);
        connProp.put(Context.INITIAL_CONTEXT_FACTORY, NamingContextFactory.class.getName());
        connProp.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");

        InitialContext initContext;
        try {
            initContext = new InitialContext();

            if (connProp != null && !connProp.isEmpty()) {
                for (String sKey : connProp.keySet()) {
                    initContext.addToEnvironment(sKey, connProp.get(sKey));
                }
            }
            Object oTemp = initContext.lookup("jmx/rmi/RMIAdaptor");
            if (oTemp != null) {
                rtnVal = RMIAdaptor.class.cast(oTemp);
            }
        } catch (NamingException e) {
            e.printStackTrace();
            logger.error(e);
        }

        return rtnVal;
    }

    public static List<String> getResourcesByType(MBeanServerConnection mbsc, String resourceName, String resourceType) throws RuntimeException {
        List<String> rtn = new ArrayList<String>();
        try {
            String[] resources = (String[]) mbsc.getAttribute(new ObjectName(resourceName), "resources");
            if (resources != null) {
                for (String resource : resources) {
                    ObjectName objectName = new ObjectName(resource);
                    if (objectName.getKeyProperty("j2eeType").equals(resourceType)) {
                        rtn.add(resource);
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return rtn;
    }

    public static Set<ObjectName> queryObjectNames(RMIAdaptor mbsc, String ons) {
        Set<ObjectName> rtnVal = null;
        try {
            Set<?> onsTemp = mbsc.queryNames(new ObjectName(ons), null);
            if (onsTemp != null) {
                rtnVal = new HashSet<ObjectName>();
                for (Object obj : onsTemp) {
                    rtnVal.add(ObjectName.class.cast(obj));
                }
            }
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        return rtnVal;
    }

    public static List<String> getDeployedObjects(MBeanServerConnection mbsc, String resourceName, String j2eeType) throws RuntimeException {
        List<String> rtn = new ArrayList<String>();
        try {
            String[] resources = (String[]) mbsc.getAttribute(new ObjectName(resourceName), "deployedObjects");
            for (String resource : resources) {
                ObjectName objectName = new ObjectName(resource);
                if (objectName.getKeyProperty("j2eeType").equals(j2eeType)) {
                    rtn.add(resource);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return rtn;
    }

    public String splitString(String str) {
        String s[] = str.split("name=");
        if (s.length == 2) {
            return s[1].substring(0, s[1].indexOf(","));
        }
        return null;
    }

    public String splitString2(String str) {
        String s[] = str.split("name=");
        if (s.length == 2) {
            String s1[] = s[1].split(",");
            if (s1.length >= 2) {
                return s1[0] + "," + s1[1];
            }
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        //        RmiUtil rmiUtil = new RmiUtil();
        RMIAdaptor rmiAdapter = RmiUtil.getRmiAdaptor("192.168.0.101", 1099);
        System.out.println("-------------jboss.web:j2eeType=WebModule,*----------------");
        Set<ObjectName> managers = RmiUtil.queryObjectNames(rmiAdapter, "jboss.web:type=Manager,*");
        for (ObjectName objectName : managers) {
            System.out.println(objectName.toString());
            //            String managerName = (String) rmiAdapter.getAttribute(objectName, "className");
            // System.out.println(rmiUtil.splitString(managerName));
        }
        /*
         * System.out
         * .println("-------------jboss.web:j2eeType=Servlet,*----------------");
         * Set<ObjectName> managers1 = RmiUtil.queryObjectNames(rmiAdapter,
         * "jboss.web:j2eeType=Servlet,*"); for (ObjectName objectName :
         * managers1) { String managerName = (String)
         * rmiAdapter.getAttribute(objectName, "objectName");
         * System.out.println(rmiUtil.splitString2(managerName)); }
         */

        System.out.println("==================jboss.web:type=Manager,*=================");
        //        Set<ObjectName> managersV = RmiUtil.queryObjectNames(rmiAdapter, "jboss.web:type=Manager,*");
        for (ObjectName objectName : managers) {
            System.out.println(objectName.toString());
        }
        /*
         * JBoss配置数据
         */
        System.out.println("-------------jboss.system:type=Server----------------");
        ObjectName jbossServer = new ObjectName("jboss.system:type=Server");
        System.out.println("BuildDate: " + (String) rmiAdapter.getAttribute(jbossServer, "BuildDate"));
        System.out.println("StartDate: " + rmiAdapter.getAttribute(jbossServer, "StartDate"));
        System.out.println("Version: " + ((String) rmiAdapter.getAttribute(jbossServer, "Version")).replaceAll("[(].*[)]", ""));
        System.out.println("VersionName: " + (String) rmiAdapter.getAttribute(jbossServer, "VersionName"));
        System.out.println();
        System.out.println();

        System.out.println("-------------jboss.system:type=ServerInfo--------------------");
        ObjectName jbossServerInfo = new ObjectName("jboss.system:type=ServerInfo");
        System.out.println("AvailableProcessors: " + rmiAdapter.getAttribute(jbossServerInfo, "AvailableProcessors"));
        System.out.println("MaxMemory: " + rmiAdapter.getAttribute(jbossServerInfo, "MaxMemory"));
        System.out.println("FreeMemory: " + rmiAdapter.getAttribute(jbossServerInfo, "FreeMemory"));
        System.out.println("TotalMemory: " + rmiAdapter.getAttribute(jbossServerInfo, "TotalMemory"));
        System.out.println("HostName: " + (String) rmiAdapter.getAttribute(jbossServerInfo, "HostName"));
        System.out.println("JavaVendor: " + (String) rmiAdapter.getAttribute(jbossServerInfo, "JavaVendor"));
        System.out.println("JavaVersion: " + (String) rmiAdapter.getAttribute(jbossServerInfo, "JavaVersion"));
        System.out.println("JavaVMName: " + (String) rmiAdapter.getAttribute(jbossServerInfo, "JavaVMName"));
        System.out.println("JavaVMVendor: " + (String) rmiAdapter.getAttribute(jbossServerInfo, "JavaVMVendor"));
        System.out.println("JavaVMVersion: " + (String) rmiAdapter.getAttribute(jbossServerInfo, "JavaVMVersion"));
        System.out.println("OSName: " + (String) rmiAdapter.getAttribute(jbossServerInfo, "OSName"));
        System.out.println();
        System.out.println();

        System.out.println("-------------jboss.system:type=ServerConfig--------------------");
        ObjectName jbossServerConfig = new ObjectName("jboss.system:type=ServerConfig");
        System.out.println("HomeURL: " + ((java.net.URL) rmiAdapter.getAttribute(jbossServerConfig, "HomeURL")).toString());
        System.out.println("ServerConfigURL: " + ((java.net.URL) rmiAdapter.getAttribute(jbossServerConfig, "ServerConfigURL")).toString());
        System.out.println("ServerName: " + (String) rmiAdapter.getAttribute(jbossServerConfig, "ServerName"));

        Set<ObjectName> j2eeDomains = queryObjectNames(rmiAdapter, "jboss.management.local:j2eeType=J2EEDomain,name=jboss.management.local");
        for (ObjectName j2eeDomain : j2eeDomains) {
            ObjectName onTemp = new ObjectName(rmiAdapter.getAttribute(j2eeDomain, "objectName").toString());
            String serverName = onTemp.toString();
            System.out.println("onTemp: " + onTemp.toString());
            System.out.println("onTempName: " + onTemp.getKeyProperty("name"));

            // 获取server信息System.out.println();
            System.out.println();
            System.out.println();

            System.out.println("------------------------Severs信息--------------------------");
            String[] servers = (String[]) rmiAdapter.getAttribute(new ObjectName(serverName), "servers");
            for (String server : servers) {
                System.out.println("-------------" + server);
                ObjectName onServerTemp = new ObjectName(server);
                System.out.println("serverVendor: " + (String) rmiAdapter.getAttribute(onServerTemp, "serverVendor"));
                System.out.println("serverVersion" + (String) rmiAdapter.getAttribute(onServerTemp, "serverVersion"));
                System.out.println("onServerTempName: " + onServerTemp.getKeyProperty("name"));
                System.out.println();
                System.out.println();
                // JVM
                System.out.println("------------------------JVM--------------------------");
                String[] jvms = (String[]) rmiAdapter.getAttribute(new ObjectName(server), "javaVMs");
                for (String jvm : jvms) {
                    ObjectName onJvmTemp = new ObjectName(jvm);
                    System.out.println(jvm);
                    System.out.println("javaVendor: " + (String) rmiAdapter.getAttribute(onJvmTemp, "javaVendor"));
                    System.out.println("javaVersion: " + (String) rmiAdapter.getAttribute(onJvmTemp, "javaVersion"));
                    System.out.println("node: " + (String) rmiAdapter.getAttribute(onJvmTemp, "node"));
                    System.out.println("onJvmTempName: " + onJvmTemp.getKeyProperty("name"));
                    System.out.println();
                    System.out.println();

                    // JVM性能数据
                    System.out.println("------------------------JVM--------------------------");
                    ObjectName onJvmPerf = new ObjectName(jvm);
                    if ((Boolean) rmiAdapter.getAttribute(onJvmPerf, "statisticsProvider")) {
                        Stats stats = (Stats) rmiAdapter.getAttribute(onJvmPerf, "stats");
                        Statistic[] statistics = stats.getStatistics();
                        for (Statistic statistic : statistics) {
                            if (statistic.getName().equals("HeapSize")) {
                                System.out.println(((BoundedRangeStatistic) statistic).getCurrent());
                                System.out.println(((BoundedRangeStatistic) statistic).getHighWaterMark());
                                continue;
                            }
                            if (statistic.getName().equals("UpTime")) {
                                System.out.println(((CountStatistic) statistic).getCount());
                            }
                        }
                    }
                }
                System.out.println();
                System.out.println();
                // JTA
                System.out.println("--------------------------JTA------------------------");
                List<String> jtaResources = getResourcesByType(rmiAdapter, server, "JTAResource");
                for (String jtaResource : jtaResources) {
                    ObjectName objectName = new ObjectName(jtaResource);
                    System.out.println(objectName.getKeyProperty("name"));
                    System.out.println(jtaResource); // jta Name

                    ObjectName jtaObjectName = new ObjectName(jtaResource);
                    if (((Boolean) rmiAdapter.getAttribute(jtaObjectName, "statisticsProvider"))) {
                        Stats stats = (Stats) rmiAdapter.getAttribute(jtaObjectName, "stats");
                        Statistic[] statistics = stats.getStatistics();
                        for (Statistic statistic : statistics) {
                            if (statistic.getName().equals("ActiveCount")) {
                                System.out.println(((CountStatistic) statistic).getCount());
                                continue;
                            }
                            if (statistic.getName().equals("CommitedCount")) {
                                System.out.println(((CountStatistic) statistic).getCount());
                                continue;
                            }
                            if (statistic.getName().equals("RolledbackCount")) {
                                System.out.println(((CountStatistic) statistic).getCount());
                                continue;
                            }
                        }
                    }
                }

                System.out.println();
                System.out.println();
                // JMS
                System.out.println("--------------------------JMS------------------------");
                List<String> jmsResources = getResourcesByType(rmiAdapter, server, "JMSResource");
                for (String jmsResource : jmsResources) {
                    ObjectName objectName = new ObjectName(jmsResource);
                    System.out.println("JmsName: " + (String) objectName.getKeyProperty("name"));
                    System.out.println(jmsResource);
                }

                // JCA
                System.out.println();
                System.out.println();
                System.out.println("--------------JCA---------------");
                Set<ObjectName> jcaResources = queryObjectNames(rmiAdapter, "jboss.management.local:j2eeType=JCAResource,*");// J2EEServer="
                // +
                // ResJbossServer.class.cast(slave).getServerName()
                // + ",
                for (ObjectName jcaResource : jcaResources) {
                    System.out.println((String) jcaResource.getKeyProperty("name"));
                    System.out.println(jcaResource.toString());
                }

                // ConnectionPool
                System.out.println();
                System.out.println();
                System.out.println("--------------ConnectionPool---------------");
                Set<ObjectName> ons = queryObjectNames(rmiAdapter, "jboss.jca:service=ManagedConnectionPool,*");
                if (ons != null) {
                    for (ObjectName on : ons) {
                        System.out.println((String) on.getKeyProperty("name"));
                        System.out.println("MaxSize: " + (Integer) rmiAdapter.getAttribute(on, "MaxSize"));
                        System.out.println("ConnectionCreatedCount: " + (Integer) rmiAdapter.getAttribute(on, "ConnectionCreatedCount"));
                        System.out.println("ConnectionDestroyedCount: " + (Integer) rmiAdapter.getAttribute(on, "ConnectionDestroyedCount"));
                        System.out.println("IdleTimeoutMinutes: " + (Long) rmiAdapter.getAttribute(on, "IdleTimeoutMinutes"));
                        System.out.println("InUseConnectionCount: " + (Long) rmiAdapter.getAttribute(on, "InUseConnectionCount"));
                        System.out.println("MaxConnectionsInUseCount: " + (Long) rmiAdapter.getAttribute(on, "MaxConnectionsInUseCount"));
                    }
                }

                // ThreadPool
                System.out.println();
                System.out.println();
                System.out.println("--------------ThreadPool---------------");
                Set<ObjectName> threadPool = queryObjectNames(rmiAdapter, "*:service=ThreadPool,*");
                for (ObjectName on : threadPool) {
                    System.out.println((String) rmiAdapter.getAttribute(on, "Name"));
                    System.out.println("KeepAliveTime: " + (Long) rmiAdapter.getAttribute(on, "KeepAliveTime"));
                    System.out.println("MaximumPoolSize:" + (Integer) rmiAdapter.getAttribute(on, "MaximumPoolSize"));
                    System.out.println("MaximumQueueSize: " + (Integer) rmiAdapter.getAttribute(on, "MaximumQueueSize"));
                    System.out.println("MinimumPoolSize: " + (Integer) rmiAdapter.getAttribute(on, "MinimumPoolSize"));
                    System.out.println("PoolNumber: " + (Integer) rmiAdapter.getAttribute(on, "PoolNumber"));
                    System.out.println("QueueSize: " + (Integer) rmiAdapter.getAttribute(on, "QueueSize"));
                }

                // Web
                System.out.println();
                System.out.println();
                System.out.println("--------------Web---------------");
                List<String> webModules = getDeployedObjects(rmiAdapter, server, "WebModule");
                for (String webModule : webModules) {
                    ObjectName onWebTemp = new ObjectName(webModule);
                    System.out.println((String) onWebTemp.getKeyProperty("name"));
                    System.out.println("J2EEApplication: " + (String) onWebTemp.getKeyProperty("J2EEApplication"));
                    System.out.println(webModule);
                }

                // EJB
                System.out.println();
                System.out.println();
                System.out.println("--------------EJB---------------");
                List<String> ejbModules = getDeployedObjects(rmiAdapter, server, "EJBModule");
                for (String ejbModule : ejbModules) {
                    ObjectName objectName = new ObjectName(ejbModule);
                    System.out.println((String) objectName.getKeyProperty("name"));
                    System.out.println(ejbModule);

                    // EntityEJB
                    System.out.println();
                    System.out.println();
                    System.out.println("--------------EntityEJB---------------");
                    String[] ejbs = (String[]) rmiAdapter.getAttribute(new ObjectName(ejbModule), "ejbs");
                    for (String ejb : ejbs) {
                        ObjectName ejbObjectName = new ObjectName(ejb);
                        if (ejbObjectName.getKeyProperty("j2eeType").equals("EntityBean")) {
                            System.out.println((String) ejbObjectName.getKeyProperty("name"));
                            System.out.println(ejb);// EntityName
                        }
                    }

                    // StatelessEJB
                    System.out.println();
                    System.out.println();
                    System.out.println("--------------StatelessEJB---------------");
                    String[] statelessEjbs = (String[]) rmiAdapter.getAttribute(new ObjectName(ejbModule), "ejbs");
                    for (String ejb : statelessEjbs) {
                        ObjectName statelessEjbObjectName = new ObjectName(ejb);
                        if (statelessEjbObjectName.getKeyProperty("j2eeType").equals("StatelessSessionBean")) {
                            System.out.println((String) statelessEjbObjectName.getKeyProperty("name"));
                            System.out.println(ejb);// Stateless Name
                        }
                    }

                    // StatefulEJB
                    System.out.println();
                    System.out.println();
                    System.out.println("--------------StatefulEJB---------------");
                    String[] statefulEjbs = (String[]) rmiAdapter.getAttribute(new ObjectName(ejbModule), "ejbs");
                    for (String ejb : statefulEjbs) {
                        ObjectName statefulEjbObjectName = new ObjectName(ejb);
                        if (statefulEjbObjectName.getKeyProperty("j2eeType").equals("StatefulSessionBean")) {
                            System.out.println((String) statefulEjbObjectName.getKeyProperty("name"));
                            System.out.println(ejb);// StatefulName
                        }
                    }

                    // MDEJB
                    System.out.println();
                    System.out.println();
                    System.out.println("--------------MDEJB---------------");
                    String[] moduleEjbs = (String[]) rmiAdapter.getAttribute(new ObjectName(ejbModule), "ejbs");
                    for (String ejb : moduleEjbs) {
                        ObjectName moduleEjbObjectName = new ObjectName(ejb);
                        if (moduleEjbObjectName.getKeyProperty("j2eeType").equals("MessageDrivenBean")) {
                            System.out.println((String) moduleEjbObjectName.getKeyProperty("name"));
                            System.out.println(ejb);// Module Name
                        }
                    }
                }
            }
        }
        System.out.println();
        System.out.println();

        /*
         * JBoss性能数据
         */

    }
}
